----------------------------------------------------------------------------
-- AspireBid 
--
-- A bidding addon that works in cooperation with AspireML (MasterLoot).
--
-- @author Panoramix - Aspire - Bloodfeather
-- @version 1.1.4
----------------------------------------------------------------------------


AspireBid = {};

AspireBid.Defaults = {
	["MinimapPosX"]  = -71.02,
	["MinimapPosY"]  = -30.34,
	["MinimapShown"] = true,
	["ItemLevel"]    = 226,
	["AutoMode"]     = "on",
	["Plate"]        = false,
	["Mail"]         = false,
	["Leather"]      = false,
	["Cloth"]        = false,
}

-- Some Constants
AspireBid.VERSION = "1.1.4";

-- Some Global Variables;
AspireBid.MasterLooter = nil;
AspireBid.CurrentBid = nil;
AspireBid.CurrentItem = nil;
AspireBid.PlayerClass = nil;
AspireBid.PlayerArmor = nil;
AspireBid.ItemButtons = {};
AspireBid.ItemSlots = {};
AspireBid.ItemBid = nil;


-- Initialization function
AspireBid.Initialize = function(self)
	
	-- Add slash commands
	SLASH_ASPIREBID1 = "/aspirebid";
	SLASH_ASPIREBID2 = "/abid";
	
	SlashCmdList["ASPIREBID"] = function(msg)
		AspireBid.SlashCommandHandler(msg);
	end

	-- register events
	--self:RegisterEvent("CHAT_MSG_PARTY");
	--self:RegisterEvent("CHAT_MSG_RAID_LEADER");
	--self:RegisterEvent("CHAT_MSG_RAID");
	self:RegisterEvent("CHAT_MSG_ADDON");
	self:RegisterEvent("ADDON_LOADED");

	-- register listener
	self:SetScript( "OnEvent", AspireBid.OnEvent );

	-- Variables
	AspireBid.PlayerClass = select(2, UnitClass("player"));	
	AspireBid.PlayerArmor = AspireBid.WEARTABLE[AspireBid.PlayerClass];
	AspireBid.Defaults[AspireBid.PlayerArmor] = true;
	
	-- Report that the addon is loaded
	AspireBid.Print( AspireBid.VERSION .. " loaded. Type '/abid ?' for available options" );	
end

-- Event Handler
AspireBid.OnEvent = function( self, event, ...)
 	 	
	if ( event == "CHAT_MSG_ADDON" ) then	
	
		local arg1, arg2, arg3, arg4  = ...;
						
		-- start bids
		if arg1 == "AspireML_StartBid" then
		
			if ( arg2~=nil ) then

				AspireBid.MasterLooter = arg4;
				AspireBid.CurrentBid = arg2;
				AspireBid.CurrentItem = nil;
					
				if ( AspireBid.BaseGetSetting("AutoMode") == "on" ) then AspireBid.Window.Show(false); end
				return;			
			end
			
		-- close bids			
		elseif arg1 == "AspireML_CloseBid" then		
			if ( AspireBid.Window.Frame:IsVisible() ) then AspireBid.Window.Toggle(); end
			return
		end
		
		return;
	end 	 	
	
	
	if ( event == "ADDON_LOADED" ) then
		AspireBid.Minimap:AddonLoaded()
		return
	end
	
 	 	 	 	
	if (event == "CHAT_MSG_RAID" or 
		event == "CHAT_MSG_RAID_LEADER" or 
		event == "CHAT_MSG_PARTY" ) then
	
		local arg1, arg2 = ...;
		
		-- parse the itemname from the raid chat		
		local _,_,itemname = string.find(arg1, "To bid, whisper me '(.*) %[CURRENT ITEM%]'");						
		
		if ( itemname~=nil ) then

			AspireBid.MasterLooter = arg2;
			AspireBid.CurrentBid = itemname;
			AspireBid.CurrentItem = nil;
				
			if ( AspireBid.BaseGetSetting("AutoMode") == "on" ) then
				AspireBid.Window.Show(false);
			end
			return;
		end
		
		-- parse item closes
		if ( AspireBid.Window.Frame:IsVisible() and AspireBid.CurrentBid~=nil ) then
			local _,_,closedname = string.find(arg1, "Closed (.*)");
			if ( AspireBid.CurrentBid==closedname ) then
				AspireBid.Window.Toggle();
			end
			
			local _,_,cancelledname = string.find(arg1, "Canceling bidding on (.*)");
			if ( AspireBid.CurrentBid==cancelledname ) then
				AspireBid.Window.Toggle();
			end
		end
	end
end

AspireBid.ParseItem = function( s )
	local itemId = string.gsub(s,".-\124H([^\124]*)\124h.*", "%1");
	-- Then get info from link (NOTE: will return nil if item is not in local cache)
	local name, link, rarity, level, slot, itemtype, itemsubtype, texture;
	name, link, rarity, level, _, itemtype, itemsubtype, _, slot, texture = GetItemInfo(itemId);
	
	local item = {};
	if (itemId==nil or name==nil or link==nil or itemsubtype==nil) then
		return nil;
	end

	item["id"] = itemId;
	item["name"] = name;
	item["link"] = link;
	item["level"] = level;
	item["itemtype"] = itemtype; 
	item["itemsubtype"] = itemsubtype;
	item["texture"] = texture;
	
	local token = AspireBid.CanUseToken(item);
	if ( token~=nil ) then
		item["slot"] = token;
		
	elseif ( slot~=nil ) then
		item["slot"] = AspireBid.SLOTTABLE[slot];	
	end
	
	return item;
end

AspireBid.CanUseToken = function(item) 	
	local _,_,itemId = string.find( item["id"], "item:(%d*):" );
	local info = AspireBid.TOKENTABLE[itemId];
	
	if ( info==nil ) then
		return nil;
	end
	
	for i,v in ipairs( info["class"] ) do 
		if ( v==AspireBid.PlayerClass ) then
			return info["slot"];
		end
	end
	
	return nil;
end

AspireBid.IsToken = function(item)
	local _,_,itemId = string.find( item["id"], "item:(%d*):" );
	local info = AspireBid.TOKENTABLE[itemId];
	
	if ( info==nil ) then		
		return false;
	else
		return true;
	end
end

AspireBid.IsSameSlot = function( item1, item2 ) 
	
	local slot1 = item1["slot"];
	local slot2 = item2["slot"];
	
	if ( type(slot1)~="table" ) then slot1 = { slot1 }; end
	if ( type(slot2)~="table" ) then slot2 = { slot2 }; end
	
	for i,v in ipairs( slot1 ) do 	
		for j,w in ipairs( slot2 ) do 
			if ( v == w ) then
				return true;
			end
		end	
	end
	
	return false;
end

AspireBid.GetEmblems = function( )
	local cCount = GetCurrencyListSize();
	for index=1, cCount do 
		name, _, _, _, _, count = GetCurrencyListInfo(index);
		if ( name=="Emblem of Triumph" ) then
			return count;
		end
	end
	
	return 0;
end

AspireBid.CanWear = function(item)	
		
	-- check if item is a token
	local token = AspireBid.CanUseToken(item);
	
	if ( token~=nil ) then
		return true;
	end	
	
	local slot = item["slot"];
	
	-- if slot is array, get first item
	if ( type(slot)=="table" ) then
		slot = slot[1];
	end	
	
	-- cant wear
	if ( slot==nil or slot==0 ) then
		return false;
	end
		
	-- check if it has class restrictions
	if ( not IsEquippableItem( item["link"] ) ) then
		return false;
	end	
	
	-- check item level
	if ( item["level"] < tonumber( AspireBid.LocalGetSetting( "ItemLevel" ) ) ) then
		return false;
	end
	
	-- neck/cloak/rings/trinkets
	if ( slot==2 or slot==11 or slot==12 or slot==13 or slot==14 or slot==15 ) then
		return true;
	end
	
	-- weapons/ranged/relics
	if ( slot==16 or slot==17 or slot==18 or slot==19 ) then
		local weapons = AspireBid.WEAPONSTABLE[AspireBid.PlayerClass];
		if ( weapons~=nil ) then			
			for k,v in ipairs(weapons) do 
				if ( item["itemsubtype"]==v ) then	
					if ( v=="Miscellaneous" ) then
						return slot==17;
					else
						return true;
					end
				end				
			end
		end
		
		-- cant use this weapon
		return false;
	end
	
	-- regular armor
	if ( AspireBid.LocalGetSetting( item["itemsubtype"] ) ) then
		return true;
	end	
	
	return false;
end

AspireBid.GetCurrentSlots = function( item )	
	local availableItems = {};
	
	-- get current equipment
	local slots = item["slot"];
	if ( type(slots) ~= "table" ) then slots = { slots }; end
	
	for i,slot in ipairs(slots) do 
		-- get itemlink for slot
		local itemLink = GetInventoryItemLink("player", slot);
		if ( itemLink~= nil ) then
			local equipItem = AspireBid.ParseItem( itemLink );
			if ( equipItem~=nil ) then
				table.insert(availableItems, equipItem);
			end
		end
	end	
	
	-- only bid with wearing gear on trophies
	if ( item["name"] == "Trophy of the Crusade" ) then
		return availableItems;
	end
	 
	-- loop over all bags
	for bagId=0, NUM_BAG_SLOTS do
		local bagSlots = GetContainerNumSlots( bagId );		
		-- loop over all slots of the bag
		for bagSlotIdx=0, bagSlots do
			-- get the itemLink for the bag slot
			local itemLink = GetContainerItemLink( bagId, bagSlotIdx );
			if ( itemLink~=nil ) then
				-- get item info for this item
				local bagItem = AspireBid.ParseItem( itemLink );
				if ( bagItem~=nil ) then	
					-- test if the item has the same slot
					if ( AspireBid.IsSameSlot( item, bagItem ) and not AspireBid.IsToken(bagItem) ) then
						table.insert(availableItems, bagItem);
					end					
				end
			end
		end		
	end		
	
	return availableItems;
end



AspireBid.CompareItem = function( item1, item2 )

	if ( item1 == nil or item2 == nil or item1["link"] == nil or item2["link"] == nil ) then
		return nil;
	end

	local statDelta = GetItemStatDelta( item1["link"], item2["link"] );
	return statDelta;
end


AspireBid.SlashCommandHandler = function( msg )
	
	msg = string.lower( msg );
	
	if ( msg=="" or msg==nil ) then
		AspireBid.Window.Toggle();
	
	elseif ( msg=="on" ) then
		AspireBid.BaseSetSetting( "AutoMode", "on" );
		AspireBid.Print( "Mode set to ON" );
			
	elseif ( msg=="off" ) then
		AspireBid.BaseSetSetting( "AutoMode", "off" );
		AspireBid.Print( "Mode set to OFF. Type /abid to bid when items are posted" ); 
		
	elseif ( msg=="minimap" ) then
		AspireBid.Minimap:Toggle();
	
	elseif ( msg=="config" ) then
		AspireBid.Config.Toggle();
	
	elseif ( msg=="test" ) then
		AspireBid.MasterLooter = "Panoramix";
		--local _,link = GetItemInfo("52025"); -- trophy
		AspireBid.CurrentBid = "\124cffa335ee\124Hitem:52025:0:0:0:0:0:0:0:0\124h[Vanquisher's Mark of Sanctification]\124h\124r";
		AspireBid.ItemBid = nil;
		AspireBid.Window.Show(false); 		
	
	else
		AspireBid.Print( "Commands:" );
		AspireBid.Print( "   /abid           - Show Bid Window" );
		AspireBid.Print( "   /abid on        - Show the window on every usable loot." );
		AspireBid.Print( "   /abid off       - Disable to automatic window. Type /abid to show it manually."  );
		AspireBid.Print( "   /abid minimap   - Toggle Minimap Button on/off." );
		AspireBid.Print( "   /abid config    - Show Configuration Window." );
	end
end


-- default AspireBid option getter
AspireBid.BaseGetSetting = function(setting)	
	local val = nil;
	if ( AspireBidConfig and AspireBidConfig["Settings"] ) then
		val = AspireBidConfig["Settings"][setting];
	end		
	if ( val == nil and AspireBid.Defaults ) then		
		val = AspireBid.Defaults[setting];
	end
	return val;
end

-- default AspireBid option setter
AspireBid.BaseSetSetting = function(setting, value)
	if ( AspireBidConfig == nil ) then
		AspireBidConfig = {["Settings"] = {}};
	end

	if ( AspireBidConfig and setting ) then
		if ( AspireBidConfig["Settings"] == nil ) then
			AspireBidConfig["Settings"] = {};
		end	
		local val = nil;
		if ( AspireBid.Defaults ) then
			val = AspireBid.Defaults[setting];
		end
		if ( val == value ) then
			AspireBidConfig["Settings"][setting] = nil;
		else			
			AspireBidConfig["Settings"][setting] = value;
		end
	end
end

-- default AspireBid local option getter
AspireBid.LocalGetSetting = function(setting)	
	local val = nil;
	if ( AspireBidLocalConfig and AspireBidLocalConfig["Settings"] ) then
		val = AspireBidLocalConfig["Settings"][setting];
	end		
	if ( val == nil and AspireBid.Defaults ) then		
		val = AspireBid.Defaults[setting];
	end
	return val;
end

-- default AspireBid local option setter
AspireBid.LocalSetSetting = function(setting, value)
	if ( AspireBidLocalConfig == nil ) then
		AspireBidLocalConfig = {["Settings"] = {}};
	end

	if ( AspireBidLocalConfig and setting ) then
		if ( AspireBidLocalConfig["Settings"] == nil ) then
			AspireBidLocalConfig["Settings"] = {};
		end	
		local val = nil;
		if ( AspireBid.Defaults ) then
			val = AspireBid.Defaults[setting];
		end
		if ( val == value ) then
			AspireBidLocalConfig["Settings"][setting] = nil;
		else			
			AspireBidLocalConfig["Settings"][setting] = value;
		end
	end
end

AspireBid.Print = function(message) 

	message = "|cff33ff99AspireBid|r: " .. message	
	DEFAULT_CHAT_FRAME:AddMessage(message);
end
